use std::collections::VecDeque;
use super::quality::AudioQualityConfig;

pub struct AudioPreprocessor {
    pub(crate) config: AudioQualityConfig,
    noise_gate_threshold: f32,
    agc_target_level: f32,
    agc_max_gain: f32,
    volume_history: VecDeque<f32>,
}

impl AudioPreprocessor {
    pub fn new(config: AudioQualityConfig) -> Self {
        Self { config, noise_gate_threshold: 0.01, agc_target_level: 0.3, agc_max_gain: 4.0, volume_history: VecDeque::with_capacity(100) }
    }
    pub fn process(&mut self, samples: &mut [f32]) {
        if self.config.volume_gain != 1.0 { for sample in samples.iter_mut() { *sample *= self.config.volume_gain; } }
        if self.config.enable_noise_reduction { self.apply_noise_gate(samples); }
        if self.config.enable_agc { self.apply_agc(samples); }
        self.apply_soft_limiter(samples);
    }
    fn apply_noise_gate(&self, samples: &mut [f32]) {
        for sample in samples.iter_mut() { if sample.abs() < self.noise_gate_threshold { *sample = 0.0; } }
    }
    fn apply_agc(&mut self, samples: &mut [f32]) {
        let rms = (samples.iter().map(|x| x * x).sum::<f32>() / samples.len() as f32).sqrt();
        self.volume_history.push_back(rms);
        if self.volume_history.len() > 50 { self.volume_history.pop_front(); }
        let avg_rms = self.volume_history.iter().sum::<f32>() / self.volume_history.len() as f32;
        if avg_rms > 0.0 && avg_rms < self.agc_target_level { let gain = (self.agc_target_level / avg_rms).min(self.agc_max_gain); for sample in samples.iter_mut() { *sample *= gain; } }
    }
    fn apply_soft_limiter(&self, samples: &mut [f32]) {
        for sample in samples.iter_mut() {
            *sample = if *sample > 1.0 { 1.0 - 0.1 * (*sample - 1.0).exp() } else if *sample < -1.0 { -1.0 + 0.1 * (-*sample - 1.0).exp() } else { *sample };
        }
    }
}


